#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;

// 为什么内存要分区？
// 答案是为了更好的管理

// 数据段也叫静态区
// 代码段也叫常量区

//int globalVar = 1; // 数据段
//static int staticGlobalVar = 1; // 数据段
//
//void Test()
//{
//	static int staticVar = 1; // 数据段
//
//	int localVar = 1; // 栈
//	int num1[10] = { 1, 2, 3, 4 }; // 栈
//
//	// char2在栈，*char2在栈，本质上是把常量区的内容拷贝过来
//	char char2[] = "abcd";
//	// pchar3在栈，*pchar3在代码段
//	const char* pChar3 = "abcd";
//	// ptr1在栈，*ptr1在堆
//	int* ptr1 = (int*)malloc(sizeof(int) * 4);
//	int* ptr2 = (int*)calloc(4, sizeof(int));
//	int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
//
//	free(ptr1);
//	free(ptr3);
//}

//int main()
//{
//	// 以下全部针对内置类型
//	// 除了用法方便，跟C语言的malloc没什么区别
//	//int* p1 = new int;
//	//int* p2 = new int[10];
//
//	// 跟C语言很像，默认不初始化，但是可以初始化
//	int* p1 = new int(10);
//	int* p2 = new int[10]{1, 2, 3, 4};
//
//	delete p1;
//	delete[] p2;
//
//	return 0;
//}

//class A
//{
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//
//	A(int a1, int a2)
//	{
//		cout << "A(int a1, int a2):" << this << endl;
//	}
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//private:
//	int _a;
//};
//
//int main()
//{
//	// new/delete 和 malloc/free最大区别是
//	// new/delete对于【自定义类型】除了开空间，还会调用构造函数和析构函数
//	A* p1 = (A*)malloc(sizeof(A));
//	// 对p1有个很尴尬的问题，就是无法初始化
//	// 因为这时候如果你无法访问成员变量，一般它们是私有
//
//	// 在这里不是匿名对象，跟它没关系
//	A* p2 = new A(1); // 会调用默认构造
//
//	free(p1);
//	delete p2;
//
//	// 内置类型是几乎是一样的
//	int* p3 = (int*)malloc(sizeof(int)); // C
//	int* p4 = new int;
//
//	free(p3);
//	delete p4;
//
//	A* p5 = (A*)malloc(sizeof(A) * 10);
//	A* p6 = new A[10]{ 1 ,2 ,3 ,{4, 5} };
//
//	free(p5);
//	delete[] p6;
//
//	return 0;
//}

// C++没有realloc的相应扩容关键字
// 自己手动扩容，扩大二倍 -> 拷贝 -> 释放

//int main()
//{
//	// new和delete是用户进行动态内存申请和释放的操作符
//	// operator new 和operator delete是系统提供的全局函数
//	// new在底层调用operator new全局函数来申请空间，
//	// delete在底层通过operator delete全局函数来释放空间。
//	// operator new (malloc) + 构造函数
//	A* p2 = new A;
//
//	// 析构 + operator delete
//	delete p2;
//
//	return 0;
//}

// malloc和opeartor new ; free和operator delete的区别
// 返回值不同

// new来创建链表！

//struct ListNode
//{
//	int _val;
//	ListNode* _next;
//
//	ListNode(int val)
//		:_val(val)
//		,_next(nullptr)
//	{}
//};
//
//int main()
//{
//	// new失败了的话，就会抛出异常
//	ListNode* pNode1 = new ListNode(1);
//	ListNode* pNode2 = new ListNode(2);
//	ListNode* pNode3 = new ListNode(3);
//
//	// 可是万一抛出异常，资源没释放就会内存泄露
//	// 可以使用智能指针，以后会讲
//	pNode1->_next = pNode2;
//	pNode2->_next = pNode3;
//
//	delete pNode1;
//	delete pNode2;
//	delete pNode3;
//
//	return 0;
//}
//
//class A
//{
//public:
//	A(int a = 0)
//		:_a(a)
//	{
//		cout << "A(int a = 0)" << this << endl;
//	}
//
//	~A()
//	{
//		cout << "~A()" << this << endl;
//	}
//private:
//	int _a;
//};
//
//// 结论：不要错配使用，否则结果不确定
//int main()
//{
//	// A* p1 = new A;
//
//	A* p2 = new A[10]; // 44，为什么？
//	delete[] p2;
//	//free(p2); // 不会调用析构函数，err
//	// 多开四个字节，存10，目的是析构的时候知道要析构几次
//	// 具体要不要多开四个字节，看你显式不显式写析构
//
//	int* p3 = new int[10]; // 40
//	free(p3);
//
//
//	return 0;
//}

// 定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象
// 构造函数不能显式调用

// new(p1)A; 对已有空间进行显式构造





